package cn.iocoder.yudao.module.energy.dal.mysql.alert;

import java.util.*;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.energy.dal.dataobject.alert.EnergyAlertDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import cn.iocoder.yudao.module.energy.controller.admin.alert.vo.*;

import java.time.LocalDateTime;

/**
 * 预警 Mapper
 *
 * @author 芋道源码
 */
@Mapper
public interface AlertMapper extends BaseMapperX<EnergyAlertDO> {

    default PageResult<EnergyAlertDO> selectPage(AlertPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<EnergyAlertDO>()
                .eqIfPresent(EnergyAlertDO::getDeviceId, reqVO.getDeviceId())
                .eqIfPresent(EnergyAlertDO::getAlertType, reqVO.getAlertType())
                .eqIfPresent(EnergyAlertDO::getStatus, reqVO.getStatus())
                .betweenIfPresent(EnergyAlertDO::getAlertTime, reqVO.getAlertTime())
                .betweenIfPresent(EnergyAlertDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(EnergyAlertDO::getId));
    }

    /**
     * 统计指定时间范围内的告警数量
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 告警数量
     */
    default Long selectCountByCreateTimeBetween(LocalDateTime startTime, LocalDateTime endTime) {
        return selectCount(new LambdaQueryWrapperX<EnergyAlertDO>()
                .between(EnergyAlertDO::getCreateTime, startTime, endTime));
    }
    
    /**
     * 获取总告警数量
     *
     * @return 总告警数量
     */
    default Long selectCount() {
        return selectCount(new LambdaQueryWrapperX<EnergyAlertDO>());
    }
    
    /**
     * 统计指定时间范围内各类型预警的数量
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 各类型预警的数量统计，key 为预警类型，value 为数量
     */
    @Select("SELECT alert_type, COUNT(*) AS count FROM energy_alert " +
            "WHERE create_time BETWEEN #{startTime} AND #{endTime} " +
            "GROUP BY alert_type")
    List<Map<String, Object>> selectAlertTypeCountByCreateTimeBetween(@Param("startTime") LocalDateTime startTime, 
                                                                      @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定时间范围内每天各类型预警的数量
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 每天各类型预警的数量统计，包含日期、预警类型和数量
     */
    @Select("SELECT DATE(create_time) AS date, alert_type, COUNT(*) AS count FROM energy_alert " +
            "WHERE create_time BETWEEN #{startTime} AND #{endTime} " +
            "GROUP BY DATE(create_time), alert_type " +
            "ORDER BY date")
    List<Map<String, Object>> selectDailyAlertTypeCountByCreateTimeBetween(@Param("startTime") LocalDateTime startTime,
                                                                           @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定时间范围内按月统计各类型预警的数量
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 每月各类型预警的数量统计，包含年月、预警类型和数量
     */
    @Select("SELECT YEAR(create_time) AS year, MONTH(create_time) AS month, alert_type, COUNT(*) AS count " +
            "FROM energy_alert " +
            "WHERE create_time BETWEEN #{startTime} AND #{endTime} " +
            "GROUP BY YEAR(create_time), MONTH(create_time), alert_type " +
            "ORDER BY year, month")
    List<Map<String, Object>> selectMonthlyAlertTypeCountByCreateTimeBetween(@Param("startTime") LocalDateTime startTime,
                                                                             @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定时间范围内按告警级别分组的预警数量
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 按告警级别分组的预警数量统计，包含告警级别和数量
     */
    @Select("SELECT level, COUNT(*) AS count FROM energy_alert " +
            "WHERE create_time BETWEEN #{startTime} AND #{endTime} " +
            "GROUP BY level")
    List<Map<String, Object>> selectAlertLevelCountByCreateTimeBetween(@Param("startTime") LocalDateTime startTime,
                                                                       @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定时间范围内按告警级别和预警类型分组的预警数量
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 按告警级别和预警类型分组的预警数量统计，包含告警级别、预警类型和数量
     */
    @Select("SELECT level, alert_type, COUNT(*) AS count FROM energy_alert " +
            "WHERE create_time BETWEEN #{startTime} AND #{endTime} " +
            "GROUP BY level, alert_type")
    List<Map<String, Object>> selectAlertLevelTypeCountByCreateTimeBetween(@Param("startTime") LocalDateTime startTime,
                                                                          @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定时间范围内每天按告警级别和预警类型分组的预警数量
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 每天按告警级别和预警类型分组的预警数量统计，包含日期、告警级别、预警类型和数量
     */
    @Select("SELECT DATE(create_time) AS date, level, alert_type, COUNT(*) AS count FROM energy_alert " +
            "WHERE create_time BETWEEN #{startTime} AND #{endTime} " +
            "GROUP BY DATE(create_time), level, alert_type " +
            "ORDER BY date")
    List<Map<String, Object>> selectDailyAlertLevelTypeCountByCreateTimeBetween(@Param("startTime") LocalDateTime startTime,
                                                                               @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计指定时间范围内按月、告警级别和预警类型分组的预警数量
     *
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 按月、告警级别和预警类型分组的预警数量统计，包含年月、告警级别、预警类型和数量
     */
    @Select("SELECT YEAR(create_time) AS year, MONTH(create_time) AS month, level, alert_type, COUNT(*) AS count " +
            "FROM energy_alert " +
            "WHERE create_time BETWEEN #{startTime} AND #{endTime} " +
            "GROUP BY YEAR(create_time), MONTH(create_time), level, alert_type " +
            "ORDER BY year, month")
    List<Map<String, Object>> selectMonthlyAlertLevelTypeCountByCreateTimeBetween(@Param("startTime") LocalDateTime startTime,
                                                                                 @Param("endTime") LocalDateTime endTime);
    
    /**
     * 统计所有按告警级别分组的预警数量
     *
     * @return 按告警级别分组的预警数量统计，包含告警级别和数量
     */
    @Select("SELECT level, COUNT(*) AS count FROM energy_alert GROUP BY level")
    List<Map<String, Object>> selectAlertLevelCount();
    
    /**
     * 统计所有按告警级别和预警类型分组的预警数量
     *
     * @return 按告警级别和预警类型分组的预警数量统计，包含告警级别、预警类型和数量
     */
    @Select("SELECT level, alert_type, COUNT(*) AS count FROM energy_alert GROUP BY level, alert_type")
    List<Map<String, Object>> selectAlertLevelTypeCount();
    
    /**
     * 统计所有告警级别为指定级别的各类型预警数量
     *
     * @param level 告警级别
     * @return 各类型预警数量统计，包含预警类型和数量
     */
    @Select("SELECT alert_type, COUNT(*) AS count FROM energy_alert WHERE level = #{level} GROUP BY alert_type")
    List<Map<String, Object>> selectAlertTypeCountByLevel(@Param("level") String level);
} 